﻿/*****************************************************************//**
 * @file    FITKGraphObjectArrow.h
 * @brief   Graph object for showing direction.
 *
 * @author  ChengHaotian (yeguangbaozi@foxmail.com)
 * @date    2024-12-12
 *********************************************************************/

#ifndef __FITKGRAPHOBJECTARROW_H__
#define __FITKGRAPHOBJECTARROW_H__

#include "FITKGraphObjectFixedSizeBase.h"

#include "FITKVTKGraphAdaptorAPI.h"

// Forward declaration
class vtkPoints;
class vtkUnstructuredGrid;
class vtkDoubleArray;
class vtkArrowSource;

namespace Exchange
{
    /**
     * @brief   Graph object for showing direction.
     * @author  ChengHaotian (yeguangbaozi@foxmail.com)
     * @date    2024-12-12
     */
    class FITKVTKGRAPHADAPTORAPI FITKGraphObjectArrow : public FITKGraphObjectFixedSizeBase
    {
        // Regist
        FITKGraphObjectRegist(FITKGraphObjectArrow, FITKGraphObjectFixedSizeBase);
        FITKCLASS(Exchange, FITKGraphObjectArrow);

    public:
        /**
         * @brief   Constructor.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-12
         */
        FITKGraphObjectArrow();

        /**
         * @brief   Destructor.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-12
         */
        ~FITKGraphObjectArrow();

        /**
         * @brief   Unused.[override]
         * @return  Is the graph object valid
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2025-01-21
         */
        bool isValid() override
        {
            return true;
        }

        /**
         * @brief   Show or hide graph object.[override]
         * @param   visibility: The visibility of graph object
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-12
         */
        void setVisible(bool visibility) override;

        /**
         * @brief   Update the load actors by current step.[override]
         * @param   forceUpdate: Force update[default]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-12
         */
        void update(bool forceUpdate = false) override;

        /**
         * @brief   Unused.[override]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-12
         */
        void updateVisibility() override;

        /**
         * @brief   Unused.[override]
         * @param   dataObjId: The data object id
         * @return  Has relation
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-12
         */
        bool isRelatedTo(int dataObjId) override;

        /**
         * @brief   Set the arrow position.
         * @param   pos: The position
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-12
         */
        void setPosition(double* pos);

        /**
         * @brief   Set the arrow position.
         * @param   px: The position of x
         * @param   py: The position of y
         * @param   pz: The position of z
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-12
         */
        void setPosition(double px, double py, double pz);

        /**
         * @brief   Set the arrow direction.
         * @param   dir: The direction
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-12
         */
        void setDirection(double* dir);

        /**
         * @brief   Set the arrow direction.
         * @param   dx: The direction of x
         * @param   dy: The direction of y
         * @param   dz: The direction of z
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-12
         */
        void setDirection(double dx, double dy, double dz);

    private:
        /**
         * @brief   Initialize.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-12
         */
        void init();

        /**
         * @brief   Generate te actor.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-12
         */
        void generateGraph();

        /**
         * @brief   Unused.[override]
         * @return  The visibility
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-12
         */
        bool getDataVisibility() override;

    private:
        /**
         * @brief   The arrow actor.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-12
         */
        FITKGraphActor* m_fActor;

        /**
         * @brief   The grid data for glyph.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-12
         */
        vtkUnstructuredGrid* m_ugrid{ nullptr };

        /**
         * @brief   The real points of the load or BC.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-12
         */
        vtkPoints* m_points{ nullptr };

        /**
         * @brief   The normal data.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-12
         */
        vtkDoubleArray* m_normal{ nullptr  };

        /**
         * @brief   The scalar data.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-12
         */
        vtkDoubleArray* m_scalar{ nullptr };

        /**
         * @brief   The arrow source.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-12
         */
        vtkArrowSource* m_arrowSrc{ nullptr };

        /**
         * @brief   The line width of the glyph actor.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-12
         */
        double m_glyphLineWidth = 2.;

    };
}   // namespace Exchange

#endif // __FITKGRAPHOBJECTARROW_H__
